#include "common.h"
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/select.h>
#include <unistd.h>
#include <errno.h>
#include "p_lib.h"
#include <ctype.h>

extern Common_Data 	Data;
extern IMSI_Data	Para;
char *hex2str(unsigned char *data, uint32 len)
{
//    printf("--------------------------------dump begin -------------------------------\n");
    char hex_string[len * 3 + 1];
    for(int i = 0; i < len; i++) {
        sprintf(&hex_string[3 * i] , "%02hhx%s", data[i], " ");
//        printf("%02hhx%s%s", data[i], " ", (i + 1) % 16 == 0 ? "\n": "");
    }
    printf("\n");
    hex_string[len * 3 + 1] = '\0';
//    printf("--------------------------------dump end -------------------------------\n");
    return hex_string;
}
static int write_sim_data(unsigned char *Buf, int iLen)
{
    int status = 0;
    if(Data.Android_Socket_fd <= 0 )
    {
        DBUG("[write_sim_data] Android_Socket_fd <= 0");
        return -1;
    }
    DBUG("Write data to android socket: %d", iLen);
    hex2str(Buf, iLen);
    status = write_data(Buf, iLen, Data.Android_Socket_fd);
    if(status < 0)
    {
        DBUG("[write_sim_data]:write sim uart error,");
        return -2;
    }

    return iLen;
}

static int read_sim_data(unsigned char *Buf, int iLen, int iTimeOut)
{
    int iRetLen = 0;

    if(Data.Android_Socket_fd <= 0 )
    {
        DBUG("[read_sim_data] Android_Socket_fd <= 0\n");
        return -1;
    }

    //iRetLen = read_data(Buf, iLen, iTimeOut, Data.Android_Socket_fd);


	iRetLen = recv(Data.Android_Socket_fd, Buf, iLen, MSG_DONTWAIT);
    DBUG("Read data from android socket:");
    hex2str(Buf, iLen);
	

    return iRetLen;
}

int VSIM_APDU_Para_Test(unsigned char *RecvBuf, int RecvLen, APDU_HEAD *head, int TimeOut)
{
	int status = 0;

	if((RecvBuf == NULL)||(RecvLen < 0))
	{
		DBUG("para error\n");
		return -1;
	}

	if(RecvLen < head->LcLe)
	{
		status = read_sim_data(RecvBuf + RecvLen , (head->LcLe - RecvLen ), TimeOut);
		if((status + RecvLen)!= head->LcLe) 
			return -2;
	}

	return 0;
}

/*
void VUSIM_ReProcessByte(unsigned char INS)
{
	unsigned char ins = INS;
	write_sim_data(&ins, 1);

	return;
}
*/
void VUSIM_RetData(unsigned char *Buf, int lenth)
{	
	if(lenth <= 0)
	{
		DBUG("[VUSIM_RetData]:lenth error\n");
		return;
	}
	write_sim_data(Buf, lenth);

	return;
}

int VUSIM_APDU_HeadDet(unsigned char *Buf, int iLen)
{
    if(Buf == NULL)
    {
        return -1;
    }

    if((iLen == 4)&&(Buf[0] == 0xFF)&&(Buf[1] == 0x10))
    {
        DBUG("PPS finish\n");
        return 0;
    }

    if(iLen < 5)
    {
        if(0 > read_sim_data(iLen + Buf, 5 - iLen, 50))
        {
            return -2;
        }
    }

    if((0x00 == Buf[0])||(0x80==Buf[0])||(0xA0==Buf[0]))
    {
        //DBUG( "APDU head get\n");
        return 1;
    }
    else
    {
        return -2;
    }
}

void VUSIM_FCT_UPDATE(VUSIM_STA *sta, unsigned char *buf, unsigned char len)
{
    char FctName[128] = {0};
    int status = 0;
    unsigned char * p_temp = Data.File_FCT;
    strcpy(FctName, "/data/meeyoo/current/FCT.dat");
    p_temp += (sta->FCT_point);
    memcpy(p_temp, buf, len);
    PrintDebuf("Update data is ", buf, len);
    status = File_Update(FctName, buf, len, sta->FCT_point);

    sprintf(FctName, "/data/meeyoo/%s/FCT.dat", Para.sIMSI);
    DBUG("update to file %s \n", Para.sIMSI);
    status = File_Update(FctName, buf, len, sta->FCT_point);

    return;
}

int TT_Dat_Pack1(unsigned char * pData,int iLen,unsigned char *Head, unsigned char *Dst)
{
	if((pData == NULL)||(iLen <= 0)||(Head == NULL)||(Dst == NULL)) return -1;
	memcpy(Dst, Head, 5);
	memcpy(Dst+5, pData, iLen);

	return (5 + iLen);
}

int TT_Dat_Pack2(unsigned char *Src, int iLen, unsigned char cnt, unsigned char *Dst)
{
    int size = sizeof(TT_Data);//add by lk 20151008
	TD_ComProtocl_SendFrame_t Snd_Frame;
	memset(&Snd_Frame, 0, sizeof(TD_ComProtocl_SendFrame_t));

	memcpy(Snd_Frame.Frame_Data, Para.IMSI, IMSI_LEN);
    Snd_Frame.Frame_Data[IMSI_LEN] = cnt;
    memcpy(IMSI_LEN + 1 + Snd_Frame.Frame_Data, Src, iLen);
    memcpy(IMSI_LEN + 1 + Snd_Frame.Frame_Data + iLen, &Para.Spm_Para, size);
    size = 10 + iLen + size;

	Snd_Frame.Cmd_TAG = 0x83;
	Snd_Frame.FrameSize = size;

	memcpy(Dst, &Snd_Frame, size + 2);

    return size + 2;
}

void APDU_Send_Byte_Ins(APDU_HEAD *head, VUSIM_STA *VS)
{
	//VUSIM_ReProcessByte(head->INS);
	VS->APDU_STAGE = APDU_STAGE1;

	return ;
}

int Set_Atr_Reboot_Cnt(int iCnt)
{
	char p_Buf[10] = {0};
    sprintf(p_Buf, "%d", iCnt);

	return 0;
}

int Get_Atr_Reboot_Cnt(void)
{
	int iRet = 0;
	char sBuf[128] = {'\0'};

    iRet = access(ATR_REBOOT_CNT_FILE, F_OK);
    if(iRet < 0)
    {
        Set_Atr_Reboot_Cnt(0);
		return 0;
    }
    
	return 0;
}

int Get_Data_By_TimeOut(int Fd, int Second, int millSend)
{
	int iRtn = 0;
    struct timeval tv;
    fd_set fdsRead;

    if(Fd < 0 )
        return -1;

    tv.tv_sec = Second;
    tv.tv_usec = (millSend * 1000);

    FD_ZERO(&fdsRead);
    FD_SET(Fd, &fdsRead);

    iRtn = select(Fd + 1, &fdsRead, NULL, NULL, &tv);

    if(iRtn < 0)
        return -2;
    else if(iRtn == 0)
        return 0;

    return iRtn;
}
